--Copyright (C) 2013 wgm.china@gmail.com (王光明)
--vss.ssdb.utils为所有list方法的公共函数

local strfind 		= string.find
local strsub  		= string.sub
local strbyte 		= string.byte
local strrep  		= string.rep
local strchar 		= string.char
local strrep 		= string.rep
local strlen 		= string.len
local type   		= type
local pairs   		= pairs
local ngx	  		= ngx 
local tb_insert		= table.insert
local tonumber		= tonumber

-------1定义公共组件(开始)---------------
local db           = require("gcs.db")
-------1定义公共组件（结束）----------------
-------2加载配置文件（开始）----------------

-------2加载配置文件（结束）----------------
module(...)
local version = '1.2'

--get version 中保存的版本号
function get_version()
	return version
end

--返回SSDB数据库
local function get_ssdb_db()
	local ssdb_db,err = db.ssdb_connect()
	return ssdb_db,err
end

--关闭SSDB数据库
local function close_ssdb_db(ssdb)
	return db.ssdb_close(ssdb)
end


function push(lr,list_name,id)
	local ssdb_db,err = get_ssdb_db()
	if not ssdb_db then return nil,err end
	local score = ngx.now()
	local res ,err 
	if lr == "l" then
		res,err = ssdb_db:zset(list_name,id,0-score)
	else
		res,err = ssdb_db:zset(list_name,id,score)
	end	
	close_ssdb_db(ssdb_db)
	if res and res ~=ngx.null then
		return id
	else
		return nil,err
	end
	
end

function pop(lr,list_name)
	local ssdb_db,err = get_ssdb_db()
	if not ssdb_db then return nil,err end
	local res,err,id
	local score = ngx.now()
	res,err = ssdb_db:zsize(list_name)
	if not res then return 0 end
	if not res[1] then return 0 end
	if res[1] == "0" then return 0 end
	if lr == "l" then
		--从最左边取值
		res,err = ssdb_db:zscan(list_name,'',0-score,'',1)
	else
		--从最右边取值
	    res,err = ssdb_db:zrscan(list_name,'',score,'',1)
	end
	--local res = {}
	--res[1] = 5
	if res then
		if res == ngx.null or res[1] == "ok" then
			return 0
		else
			local id = res[1]
			ssdb_db:zdel(list_name,id)
			return id
			
		end
	else
		return nil,err
	end		
	close_ssdb_db(ssdb_db)	
end

function zdel(list_name,id)
	local ssdb_db,err = get_ssdb_db()
	if not ssdb_db then return nil,err end
	local res,err = ssdb_db:zdel(list_name,id)
	return res,err
end

function hset(list_name,id,code)
	local ssdb_db,err = get_ssdb_db()
	if not ssdb_db then return nil,err end
	local res,err = ssdb_db:hset(list_name,id,code)
	return res,err
end


function count(list_name)
	local ssdb_db,err = get_ssdb_db()
	if not ssdb_db then return nil,err end
	local res,err
	local tb_res = {}
	res,err = ssdb_db:zsize(list_name)
	if res == ngx.null or not res then res = 0 end
	close_ssdb_db(ssdb_db)	
	return tonumber(res[1]),err
end

function set(data)
	local ssdb_db,err = get_ssdb_db()
	if not ssdb_db then return nil,err end
	local res ,err 
	local tb_res
	ssdb_db:init_pipeline()
	for key,value in pairs(data) do
		ssdb_db:set(key,value)
	end
	local res, err = ssdb_db:commit_pipeline()
	close_ssdb_db(ssdb_db)
	return true,err
end



function setx(key,value,time)
	local ssdb_db,err = get_ssdb_db()
	if not ssdb_db then return nil,err end
	local res ,err 
	local tb_res
	ssdb_db:init_pipeline()
	ssdb_db:setx(key,value,time)
	local res, err = ssdb_db:commit_pipeline()
	close_ssdb_db(ssdb_db)
	return true,err
end


function get(data)
	local ssdb_db,err = get_ssdb_db()
	if not ssdb_db then return nil,err end
	local res ,err 
	local tb_res = {}
	for _,key in pairs(data) do
		res,err = ssdb_db:get(key)
		if not res then return nil,err end
		if res == ngx.null or res[1] == "not_found" then res[1] = "" end
		tb_res[key] = res[1]
	end
	close_ssdb_db(ssdb_db)
	return tb_res,err
end

function del(data)
	local ssdb_db,err = get_ssdb_db()
	if not ssdb_db then return nil,err end
	local res ,err 
	local tb_res = {}
	for _,key in pairs(data) do
		res,err = ssdb_db:del(key)
		if not res then return nil,err end
		if res == ngx.null then res = "" end
		tb_res[key] = res[1]
	end
	close_ssdb_db(ssdb_db)
	return tb_res,err
end

function get1(data)
	local ssdb_db,err = get_ssdb_db()
	if not ssdb_db then return nil,err end
	local res ,err 
	local tb_res = {}
	for _,key in pairs(data) do
		res,err = ssdb_db:get(key)
		if not res then return nil,err end
		if res == ngx.null or res[1] == "not_found" then res[1] = 0 end
		tb_res[key] = res[1]
	end
	close_ssdb_db(ssdb_db)
	return tb_res,err
end

function incr(data)
	local ssdb_db,err = get_ssdb_db()
	if not ssdb_db then return nil,err end
	local res ,err 
	local tb_res = {}
	for key,value in pairs(data) do
		value = tonumber(value) or 0
		res,err = ssdb_db:incr(key,value)
		if not res then return nil,err end
		tb_res[key] = res[1]
	end
	close_ssdb_db(ssdb_db)
	return tb_res,err
end
